package Server;


import i_business.I_User;

import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;

import business_service.ServerFileHelper;
import business_service.ServerService;
import business_service.UserService;

import Protocol.utility.NetAddress;
import Protocol.admin.AdminBehave_Q;
import Protocol.admin.AdminBehave_R;
import Protocol.app.FileDelete_Q;
import Protocol.app.FileDelete_R;
import Protocol.app.FileDownload_R;
import Protocol.app.FileUpload_R;
import Protocol.app.SearchHobby_R;
import Protocol.noticeMsgWord.NoticeMsgWord_Q;
import Protocol.noticeMsgWord.NoticeMsgWord_R;
import Protocol.threadStatus.ThreadStatus_R;
import Protocol.user.BasePersonInfo;
import Protocol.user.BasePersonInfo_Q;
import Protocol.user.BasePersonInfo_R;
import Protocol.user.DetailPersonInfo_Q;
import Protocol.user.DetailPersonInfo_R;
import Protocol.user.Login_Q;
import Protocol.user.Login_R;
import Protocol.user.Logout_Q;
import Protocol.user.Logout_R;

public class ServerHandler {		
	private ObjectOutputStream     	out;
	private Socket					clientSocket;	
	private HashMap<Integer, ObjectOutputStream>      userOutMap;
	private BasePersonInfo	    	clientBpi;
	private ServerService		  	service;
	
	ServerHandler(ServerListener  sh) {
		service = new   ServerService();
		clientSocket= sh.getClientSocket();
		out = sh.getObjectOut();
		userOutMap = sh.getServer().getServerData().getUserOutMap();
	}
	public void handleObjectMsg(Object   msg) {
		if(msg instanceof  Login_R) {
			handleLogin((Login_R)msg);
		}
		else if(msg instanceof Logout_R) {
			handleLogout((Logout_R)msg);
		}
		else if(msg instanceof BasePersonInfo_R ) {
			handleBaseInfo((BasePersonInfo_R) msg);
		}
		else if(msg instanceof NoticeMsgWord_R) {
			handleNoticeMsgWord((NoticeMsgWord_R)msg);
		}
		else if(msg instanceof ThreadStatus_R) {
			handleTOLR((ThreadStatus_R)msg);
		}
		else if(msg instanceof FileUpload_R) {
			handleFileUpload((FileUpload_R)msg);
		}
		else if(msg instanceof FileDelete_R) {
			handleFileDelete((FileDelete_R) msg);
		}
		else if(msg instanceof FileDownload_R) {
			handleFileDownload((FileDownload_R)msg);
		}
		else if(msg instanceof AdminBehave_R)  {
			handleAdminBehave((AdminBehave_R)msg);
		}
		else if(msg instanceof SearchHobby_R) {
			handleSearchHobby((SearchHobby_R)msg);
		}
		else if(msg instanceof BasePersonInfo_R) {
			handleBasePersonInfo((BasePersonInfo_R)msg);
		}
	}
	private void handleBasePersonInfo(BasePersonInfo_R bpi){
		
	}
	private void handleSearchHobby(SearchHobby_R  shr) {
		
	}
	private void handleAdminBehave(AdminBehave_R  abr) {
		//AdminBehave_Q    abq = this.adminService.doAdmin(abr);
		
		/*try {
			out.writeObject(abq);
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
		
		
	}
	private void handleFileDownload(FileDownload_R  fdr) {
		
			String ip = clientSocket.getInetAddress().getHostAddress();
			NetAddress na = new NetAddress();
			na.setIp(ip);
			na.setPort(fdr.getPort());
			ServerFileHelper   sfh = new ServerFileHelper(na, "res\\"+clientBpi.getName()+ fdr.getFileName());
			new Thread(sfh).start();
			
			//deleteFile.
	}
	private void handleFileDelete(FileDelete_R  fdr) {
		File	deleteFile = new File("res\\"+clientBpi.getName()+fdr.getFileName());
		if(deleteFile.exists()) {
			deleteFile.delete();
			//deleteFile.
			FileDelete_Q  fdq = new FileDelete_Q();
			fdq.setStatus("true");
			fdq.setFilename(fdr.getFileName());
			try {
				out.writeObject(fdq);
				out.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else {
			FileDelete_Q  fdq = new FileDelete_Q();
			fdq.setStatus("false");
			try {
				out.writeObject(fdq);
				out.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	private void handleFileUpload(FileUpload_R  fur) {
		String ip = clientSocket.getInetAddress().getHostAddress();
		NetAddress na = new NetAddress();
		na.setIp(ip);
		na.setPort(fur.getPort());
		ServerFileHelper   sfh = new ServerFileHelper(na, "res\\"+clientBpi.getName()+ fur.getFileName());
		new Thread(sfh).start();
	}
	private void handleTOLR(ThreadStatus_R nr) {
		ObjectOutputStream   source = this.userOutMap.get(nr.getThreadLogStatus().getAuthor_id());
		
		if(nr.getThreadLogStatus().getType().equalsIgnoreCase("thread")) {
			for(ObjectOutputStream  out : this.userOutMap.values()) {
				if(!source.equals(out)){
					try {
						out.writeObject(nr);
						out.flush();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			// remains unfinished here we must insert the nr into the database
			//  
		}
	}
/*	private void handleNotice_R(Notice_R nr) {
		ObjectOutputStream   source = this.userOutMap.get(nr.getUser_id());
		
		if(nr.getNotice().getCategory().equalsIgnoreCase("notice")) {
			for(ObjectOutputStream  out : this.userOutMap.values()) {
				if(!source.equals(out)){
					try {
						out.writeObject(nr);
						out.flush();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			// remains unfinished here we must insert the nr into the database
			//  
		}
	}*/
	private void handleNoticeMsgWord(NoticeMsgWord_R  msg) {
		//System.out.println("server received "+msg.getChatMsg());
		/*try {
			ObjectOutputStream   targetOut = this.userOutMap.get(msg.getChatMsg().getTo_id());
			if(targetOut != null) {
				//ObjectOutputStream		targetOut = new ObjectOutputStream(targetSocket.getOutputStream());
				targetOut.writeObject(msg);
				targetOut.flush();
				targetOut = null;
			}
			else {
				NoticeMsgWord_Q		cmq = new NoticeMsgWord_Q();
				cmq.setWord(null);
				out.writeObject(cmq);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
		
	}
	private void handleLogin(Login_R  request) {
		Login_Q    loginReply = service.getLogService().doLogin(request);
		//System.out.println("server:  loginreply: "+loginReply.getLogin_result());
		if(loginReply.getLogin_result().equals("success")) {
			userOutMap.put(loginReply.getClientBaseInfo().getUser_id(), out);
			clientBpi = loginReply.getClientBaseInfo();
			//loginReply.getContact().display();
			File	f=new File("res");
			ArrayList<String >   fileNameList = new ArrayList<String>();
			for(File  temp : f.listFiles()) {
				if(temp.getName().startsWith(clientBpi.getName())) {
					fileNameList.add(temp.getName().substring(clientBpi.getName().length()));
				}
			}
			loginReply.setServerFileList(fileNameList);
		}
		try {
			out.writeObject(loginReply);
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private void handleLogout(Logout_R lor) {
		//to do bellow
		
	}
	private void handleBaseInfo(BasePersonInfo_R bpi_r) {
		/*BasePersonInfo_Q    bpi_q = userService.doBasePersonInfo(bpi_r);
		try {
			out.writeObject(bpi_q);
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
	}
	private void handleDetailPersonInfo(DetailPersonInfo_R  dpi_r) {
		/*DetailPersonInfo_Q  dpi_q = userService.doDetailPersonInfo(dpi_r);
		try {
			out.writeObject(dpi_q);
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
	}
	
}
